/*
 * Copyright (c) 2025 [ByteDance Ltd. and/or its affiliates.] and/or its affiliates
 * SPDX-License-Identifier: LGPL v2.1+
*/
#ifndef ANDROID_FFmpegBaseIOCryptor_H
#define ANDROID_FFmpegBaseIOCryptor_H

#include "FFmpegIOCryptor.h"
#include <cinttypes>

#define LOG_PARAM_NOT_FOUND(param) av_log(NULL, AV_LOG_ERROR, "Param [%s] not found", (param));
#define LOG_PARAM_INVALID(param)   av_log(NULL, AV_LOG_ERROR, "Invalid param [%s]", (param));

class FFmpegBaseIOCryptor : virtual public FFmpegIOCryptor {
public:
    ~FFmpegBaseIOCryptor() override;

    virtual int prepare(const char *url, AVFormatContext *formatContext, const AVDictionary *options, const std::map<std::string, FFAny> *params) override;

    virtual void clearFormatContext() override;

protected:
    /**
     * Parse cryptor parameters
     * @param param
     * @return 0 if success, otherwise return a negative error code
     */
    virtual int parseParam(const std::map<std::string, FFAny> *params) = 0;

protected:
    /**
     * Read packet. Subclass must override it.
     * @param buf
     * @param bufSize
     * @return
     */
    virtual int readPacket(uint8_t *buf, int bufSize) = 0;

    /**
     * Seek to offset. This class provide a default implementation, subclass can override it.
     * @param offset
     * @param whence
     * @return
     */
    virtual int64_t seek(int64_t offset, int whence);

    /**
     * Read packet. Subclass must override it.
     * @param buf
     * @param bufSize
     * @return
     */
    virtual int writePacket(const uint8_t *buf, int bufSize) = 0;

private:
    static int ReadPacket(void *opaque, uint8_t *buf, int bufSize);
    static int WritePacket(void *opaque, const uint8_t *buf, int bufSize);
    static int64_t Seek(void *opaque, int64_t offset, int whence);

    void free();

protected:
    AVFormatContext *m_pFormatContext = nullptr;
    AVIOContext *m_pCryptIOCtx = nullptr;
    AVIOContext *m_pOriginalIOCtx = nullptr;

private:
    bool m_bOwnOriginalIOCtx = false;
};

#endif   // ANDROID_FFmpegBaseIOCryptor_H
